package instrarbre;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import javax.swing.JTextArea;
import progarbre.ASAProg;

public class ASABloc extends ASAInstr {

    private HashMap<String, Integer> affectation;
    private ArrayList<String> affectationLocale;
    private LinkedList<ASAInstr> instructions;

    public ASABloc() {
        this.instructions = new LinkedList<ASAInstr>();
    }

    public boolean add(ASAInstr instruction) {
        return instructions.add(instruction);
    }

    @Override
    public int getNbDeclare() {
        int nbDeclare = 0;
        for (ASAInstr instruction : instructions) {
            nbDeclare += instruction.getNbDeclare();
        }
        return nbDeclare;
    }

    @Override
    public void interpreter(HashMap<String, Integer> affectation) {
        this.affectation = new HashMap<String, Integer>(affectation);
        this.affectationLocale = new ArrayList<String>();
        for (ASAInstr instruction : instructions) {
            if (instruction instanceof ASADeclare) {
                semantique(((ASADeclare) instruction).getIdentifiants());
            }
            try {
                instruction.interpreter(this.affectation);
            }
            catch (BreakException e) {
                cleanPile();
                throw e;
            }
            catch (ContinueException e) {
                cleanPile();
                throw e;
            }
            catch (ReturnException e) {
                cleanPile();
                throw e;
            }
        }
        cleanPile();
    }

    public void semantique(ArrayList<String> affectation) {
        for (String ident : affectation) {
            if (affectationLocale.contains(ident)) {
                throw new RuntimeException("Declaration mulitple de la même variable : " + ident);
            }
            affectationLocale.add(ident);
        }
    }

    @Override
    protected String notationExplorateur(String prefixe) {
        String res = prefixe + getLabelExplorateur() + "\n";
        String prefixeSuiv = prefixe + "  ";
        for (ASAInstr e1 : instructions) {
            res += e1.notationExplorateur(prefixeSuiv);
        }
        return res;
    }

    public int getNbLocalDeclare() {
        int nbDeclare = 0;
        for (ASAInstr instruction : instructions) {
            if (instruction instanceof ASADeclare) {
                nbDeclare += instruction.getNbDeclare();
            }
        }
        return nbDeclare;
    }

    public void cleanPile() {
        for (int i = 0; i < getNbLocalDeclare(); i++) {
            ASAProg.pop();
        }
    }

    @Override
    public void setView(JTextArea area) {
        for (ASAInstr instruction : instructions) {
            instruction.setView(area);
        }
    }
}
